// 引入getToken接口参数数据类型
import type { logoutReq, UserState } from '@/store/modules/types/type'

// 引入路由类型定义
import { getToken, getUserInfo, logout } from '@/api/login'

// 引入路由
import router from '@/router/index'

// 引入常量路由
import { anyRoute, constantRoute } from '@/router/routes'

// 引入element-plus的提示框
import { ElMessage } from 'element-plus'

// 创建用户小仓库
import { defineStore } from 'pinia'

// 后端返回的数据接口，component 为字符串路径
export interface RawMenuItem {
  path: string
  name: string
  component: string
  title: string
  hidden: boolean
  icon: string
  children?: RawMenuItem[]
}

// Vue Router 使用的路由配置接口，component 为动态导入函数
export interface MenuItem {
  path: string
  name: string
  meta: any
  component: () => Promise<any>
  children?: MenuItem[]
}

// 使用 import.meta.glob 动态导入所有组件
const modules = import.meta.glob([
  '/src/layout/index.vue',
  '/src/views/**/**/index.vue',
])

// 递归设置动态菜单
function setMenu(asyncRoutes: RawMenuItem[]): MenuItem[] {
  return asyncRoutes.map(item => ({
    path: item.path || '',
    name: item.name || '',
    meta: {
      title: item.title || '',
      icon: item.icon || '',
      hidden: item.hidden || false,
    },
    component: modules[`${item.component}`],
    children: item.children && item.children.length > 0 ? setMenu(item.children) : undefined,
  }))
}

const useUserStore = defineStore('User', {
  state: (): UserState => {
    return {
      // 用户唯一标识
      token: '',
      // 菜单路由
      menuRoutes: [],
      // 用户名
      username: '',
      // 用户头像
      avatar: '',
      // 用户id
      userId: 0,
      // 按钮
      buttons: [] as string[],
    }
  },
  actions: {
    // 获取token
    async getToken(data: any) {
      try {
        const response = await getToken(data)
        // 浏览器缓存token
        // SET_ACCESSTOKEN(JSON.stringify(res))
        // 登录成功，pinia仓库保存token
        this.token = JSON.stringify(response)
        // 遍历将 constantRoute 和 anyRoute 中的路由信息添加到 路由器中
        constantRoute.forEach((item: any) => {
          router.addRoute(item)
        })
        anyRoute.forEach((item: any) => {
          router.addRoute(item)
        })

        // 获取用户信息
        const userInfo: any = await getUserInfo()
        if (userInfo.success && userInfo.code === 200) {
          // 获取用户基础信息
          this.username = userInfo.data.name
          this.avatar = userInfo.data.avatarUrl
          this.userId = userInfo.data.id
          // 获取按钮权限列表信息
          this.buttons = userInfo.data.buttons
          // 获取用户信息中的菜单权限数据
          const asyncRoutes = userInfo.data.menuAuthorities
          // 将菜单权限数据递归转换成 路由数据
          const asyncRoute = setMenu(asyncRoutes)
          // 添加动态路由到路由器中
          asyncRoute.forEach((item: any) => {
            router.addRoute(item)
          })
        }
        // 将当前路由器信息保存到 pinia仓库中
        this.menuRoutes = router.getRoutes()
        // 路由跳转
        router.push({ path: '/layout' })
        ElMessage({
          message: `登录成功`,
          type: 'success',
        })
      }
      catch (error) {
        // 捕获并处理异常
        let errorMessage = '未知错误'
        if (error instanceof Error) {
          errorMessage = error.message
        }
        ElMessage({
          message: `登录失败: ${errorMessage}`,
          type: 'error',
        })
      }
    },
    // 获取用户信息
    async fetchUserInfo() {
      try {
        const response: any = await getUserInfo()

        if (response.code === 200) {
          this.username = response.data.name
          this.avatar = response.data.avatarUrl
          this.userId = response.data.id
          return 'ok'
        }
        else {
          throw new Error(response.message || '获取用户信息失败')
        }
      }
      catch (error) {
        console.error('获取用户信息失败:', error)
        throw error // 确保错误信息能够正确传递给调用者
      }
    },
    // 退出登录
    async logout(data: logoutReq) {
      try {
        const response: any = await logout(data)

        if (response.code === 200) {
          // 注销成功
          ElMessage({
            message: `注销成功`,
            type: 'success',
          })

          // 清空pinia仓库数据
          this.token = ''
          this.username = ''
          this.avatar = ''
          this.menuRoutes = []
          this.userId = 0

          // 路由到登录页
          router.push({ path: '/OAuth2Redirect' })
        }
        else {
          // 处理非200状态码的情况
          ElMessage({
            message: `注销失败，状态码: ${response.code}`,
            type: 'error',
          })
        }
      }
      catch (error) {
        // 处理异常
        let errorMessage = '未知错误'
        if (error instanceof Error) {
          errorMessage = error.message
        }
        ElMessage({
          message: `注销失败: ${errorMessage || '未知错误'}`,
          type: 'error',
        })
      }
    },
    // 刷新动态路由
    async fetchMenuAuthorities() {
      // 遍历将 anyRoute 中的路由信息添加到 路由器中
      anyRoute.forEach((item: any) => {
        router.addRoute(item)
      })

      // 获取用户信息
      const userInfo: any = await getUserInfo()
      if (userInfo.success && userInfo.code === 200) {
        // 获取用户信息中的菜单权限数据
        const asyncRoutes = userInfo.data.menuAuthorities
        // 将菜单权限数据递归转换成 路由数据
        const asyncRoute = setMenu(asyncRoutes)
        // 添加动态路由到路由器中
        asyncRoute.forEach((item: any) => {
          router.addRoute(item)
        })
      }
    },
  },
  getters: {

  },
  persist: [
    { storage: sessionStorage, pick: [] },
    { storage: localStorage, pick: ['token', 'menuRoutes', 'username', 'avatar', 'userId', 'buttons'] },
  ],
})

// 对外暴露
export default useUserStore
